<template>
    <div>
        <div class="btn">
            <el-button type="primary" @click="addCanvas">新增画布</el-button>
            <el-button type="primary" @click="addRect">添加画笔</el-button>
            <el-button type="primary" @click="updateText">修改文本</el-button>
        </div>
        <div class="canvasContainer" id="canvasContainer" ref="canvasContainer">
        </div>
    </div>
</template>
<style lang="scss">
body {
    margin: 0;
    padding: 0;
    box-sizing: border-box;

    .canvasContainer {
        width: 1000px;
        height: 1414px;
        box-sizing: border-box;
        position: absolute;
        left: 50%;
        /* 将元素的左边缘放在父容器中心 */
        transform: translateX(-50%);
        /* 将元素向左移动自身宽度的一半，实现水平居中 */
    }
}
</style>
<script setup lang="ts">
// 框架fabricjs  其他框架konva
import { onMounted, ref, shallowRef } from 'vue';
import * as fabric from 'fabric';
import { ElMessage, } from 'element-plus';

// 画布数组对象
const canvas = shallowRef<fabric.Canvas>();
const canvasContainer = ref<HTMLDivElement>();
const currntText = ref<fabric.IText>();

// 新增画布
const addCanvas = () => {
    // 创建画布添加到容器
    const hTMLCanvasElement: HTMLCanvasElement = createCanvas();
    canvasContainer.value?.appendChild(hTMLCanvasElement);

    // 创建组件画布对象
    const canvasObj = new fabric.Canvas(hTMLCanvasElement, {});

    // 添加鼠标事件监听以开始绘制矩形
    canvasObj.on('mouse:down', onMouseDown);
    canvasObj.on('mouse:move', onMouseMove);
    canvasObj.on('mouse:up', onMouseUp);

    canvas.value = canvasObj;
};


function updateText() {
    console.log(currntText.value);
    if (currntText.value) {
        currntText.value.set({
            text: '123',
        });
        canvas.value?.renderAll();

    }
}

function onSelected(event: any) {
    // event.target 就是被选中的对象
    console.log("选中的信息：", event.target);
    console.log("左上角X坐标:", event.target.left);
    console.log("左上角Y坐标:", event.target.top);
    console.log("宽度:", event.target.width);
    console.log("高度:", event.target.height);

    if (event.target.type === 'text') {
        console.log(1);
    }

    // 检查是否选中的是一个组
    if (event.target && event.target.type === 'group') {
        // 是分组，则遍历组内的所有对象
        event.target._objects.forEach(function (object: any) {
            // 检查对象是否为 IText 类型
            if (object.type === 'text' || object.type === 'i-text') {
                // 这里可以对找到的 IText 对象进行操作，比如修改文本内容等
                currntText.value = object;
            }
        });
    } else {
        console.log('当前选中的不是分组');
    }

}

interface DragRectPosition {
    left: number,
    top: number,
    width: number,
    height: number
}

let isDrawing = false;
let startPointer: any;
let dragRectPosition: DragRectPosition | null = null;
function onMouseDown(options: any) {
    if (!options.target) {
        isDrawing = true;
        startPointer = options.pointer;
    }
}
function onMouseMove(options: any) {
    if (!isDrawing) {
        return;
    }
    const pointer = options.pointer;
    const left = Math.min(startPointer.x, pointer.x);
    const top = Math.min(startPointer.y, pointer.y);
    const width = Math.abs(pointer.x - startPointer.x);
    const height = Math.abs(pointer.y - startPointer.y);
    if (width <= 10 || height <= 10) {
        return;
    }
    dragRectPosition = {
        left,
        top,
        width,
        height,
    };
}
function onMouseUp() {
    if (!isDrawing) {
        return;
    }
    if (canvas.value && dragRectPosition) {
        // 矩形绘制
        const rect = new fabric.Rect({
            left: dragRectPosition.left,
            top: dragRectPosition.top,
            width: dragRectPosition.width,
            height: dragRectPosition.height,
            fill: 'rgba(255,0,0,0.5)',
            stroke: 'red',
            strokeWidth: 2,
        });
        // 监听选中事件
        rect.on('selected', onSelected);

        // 创建文本对象
        var text = new fabric.IText('', {
            fontSize: 16,
            // 设置文本颜色
            fill: 'white'
        });
        // 设置文本
        text.set({text:'Your Text Here'});

        // 注意：这个计算是简化的示例，实际可能需要根据文本尺寸调整
        text.set({
            left: rect.left + (rect.width / 2),
            top: rect.top + (rect.height / 2),
            originX: 'center',
            originY: 'center',
        });

        // 建组
        const group = new fabric.Group([rect, text], {
            left: dragRectPosition.left,
            top: dragRectPosition.top,
        });
        group.on('selected', onSelected);
        canvas.value.add(group);

        // // 矩形绘制
        // const rect = new fabric.Rect({
        //     left: dragRectPosition.left,
        //     top: dragRectPosition.top,
        //     width: dragRectPosition.width,
        //     height: dragRectPosition.height,
        //     fill: 'rgba(255,0,0,0.5)',
        //     stroke: 'red',
        //     strokeWidth: 2,
        // });
        // // 监听选中事件
        // rect.on('selected', onSelected);
        // canvas.value.add(rect);
        // canvas.value.renderAll();
    }
    dragRectPosition = null;
    isDrawing = false;
}

const addRect = () => {

    // 创建一个矩形对象
    var rect = new fabric.Rect({
        left: 100,
        top: 100,
        fill: 'red',
        width: 100,
        height: 100,
        lockRotation: true,  //禁止旋转
    });
    // 单独隐藏旋转控制点
    rect.setControlsVisibility({ 'mtr': false });
    // 将矩形添加到画布
    if (!canvas.value) {
        ElMessage.error('请先添加画布');
        return;
    }
    canvas.value?.add(rect);
};




// 创建画布
const createCanvas = (width: number = 1000, height: number = 1414, border: string = '1px solid black'): HTMLCanvasElement => {
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    canvas.style.border = border;
    return canvas;
};

// 获取画布上下文
const getContext = (): CanvasRenderingContext2D => {
    const canvas = document.createElement('canvas');
    canvas.width = 1500;
    canvas.height = 1000;
    canvas.style.border = '1px solid black';
    document.getElementById('canvasContainer')?.appendChild(canvas);
    // 返回2d上下文
    const ctx = canvas.getContext('2d');
    if (!ctx) {
        throw new Error('CanvasRenderingContext2D not found');
    }
    return ctx;
};

// 角度转弧度
const angletoRadian = (angle: number): number => {
    return angle * (Math.PI / 180);
};

onMounted(() => {
    // const ctx = getContext();

    // const rectangle = new Path2D();
    // rectangle.rect(10, 10, 100, 100);
    // const circle = new Path2D();
    // circle.arc(200, 100, 50, angletoRadian(0), angletoRadian(360), true);
    // circle.moveTo(125, 35);
    // circle.arc(100, 35, 25, 0, 2 * Math.PI);

    // ctx.stroke(rectangle);
    // ctx.fill(circle);

    // var p = new Path2D("M10 10 h 80 v 80 h -80 Z");
    // ctx.fill(p);



    // 二次贝塞尔曲线
    // ctx.beginPath();
    // ctx.moveTo(75, 25);
    // ctx.quadraticCurveTo(25, 25, 25, 62.5);
    // ctx.quadraticCurveTo(25, 100, 50, 100);
    // ctx.quadraticCurveTo(50, 120, 30, 125);
    // ctx.quadraticCurveTo(60, 120, 65, 100);
    // ctx.quadraticCurveTo(125, 100, 125, 62.5);
    // ctx.quadraticCurveTo(125, 25, 75, 25);
    // ctx.stroke();
    // ctx.fillStyle = 'red';
    // ctx.fill();
    // // 画文字
    // ctx.font = '12px Arial';
    // ctx.fillStyle = '#cccfff';
    // ctx.fillText('二次贝塞尔曲线', 35, 60);

    // 画圆
    //ctx.arc(200, 100, 50, angletoRadian(0), angletoRadian(360), true);
    //ctx.stroke();
    // 画线
    // ctx.moveTo(0, 0);
    // ctx.lineTo(200, 100);
    // ctx.stroke();
    // 画矩形
    // ctx.fillStyle = 'red';
    // ctx.fillRect(10, 10, 100, 100);
    // 画三角形
    // ctx.beginPath();
    // // 描边三角形
    // ctx.beginPath();
    // ctx.moveTo(125, 125);
    // ctx.lineTo(125, 45);
    // ctx.lineTo(45, 125);
    // ctx.closePath();
    // ctx.stroke();

    // 填充颜色
    //ctx.fillStyle = 'red';
    //ctx.fill();
    // ctx.fillRect(25, 25, 100, 100);
    //ctx.clearRect(45, 45, 60, 60);
    // ctx.strokeRect(50, 50, 50, 50);
});
</script>